package com.karry.web;

import cn.hutool.core.util.StrUtil;
import com.karry.pojo.Blog;
import com.karry.pojo.Comment;
import com.karry.pojo.Type;
import com.karry.pojo.User;
import com.karry.service.BlogService;
import com.karry.service.CommentService;
import com.karry.service.TypeService;
import com.karry.service.impl.BlogServiceImpl;
import com.karry.service.impl.CommentServiceImpl;
import com.karry.service.impl.TypeServiceImpl;
import com.karry.util.CommentUtil;
import com.karry.util.DianZanUtil;
import com.karry.util.JsonUtil;
import com.karry.util.XssStrUtils;
import com.karry.vo.ResultInfo;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@WebServlet("/blog")
public class BlogServlet extends HttpServlet {

    BlogService bs = new BlogServiceImpl();
    CommentService cs = new CommentServiceImpl();

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 设置首页导航栏的高亮值
        req.setAttribute("menu_page", "note");
        String method = req.getParameter("actionName").trim();

        System.out.println("blog_actionName:" + method);

        switch (method){
            //进入修改或者添加博客页面
            case "view":
                blogView(req, resp);
                break;
                //查看博客
            case "detail":
                blogDetail(req, resp);
                break;
                //执行修改或者添加操作
            case "addOrUpdate":
                addOrUpdate(req, resp);
                break;
                //删除博客
            case "delete":
                blogDelete(req, resp);
                break;
                //这里预先没设计好，导致功能重复（两个删除返回参数等等不同）
            case "delete2":
                deleteBlog(req, resp);
                break;
            case "open":
                openBlog(req, resp);
                break;
            case "close":
                closeBlog(req, resp);
                break;
            case "live":
                liveBlog(req, resp);
                break;
            case "dianZanFunction":
                dianZan(req, resp);
                break;
            case "comment":
                blogComment(req, resp);
                break;
            case "deleteComment":
                deleteComment(req, resp);
                break;
            case "liveComment":
                liveComment(req, resp);
                break;
            default:
                break;
        }

    }

    private void liveComment(HttpServletRequest req, HttpServletResponse resp) throws IOException {

        int id = Integer.parseInt(req.getParameter("id"));
        int i = cs.liveComment(id, req);
        resp.getWriter().write(i+"");
    }

    private void deleteComment(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        int id = Integer.parseInt(req.getParameter("id"));
        int i = cs.deleteComment(id, req);
        resp.getWriter().write(i+"");
    }

    private void detail(HttpServletRequest request, HttpServletResponse response){
        String blogId = request.getParameter("blogId");
        // 2. 调用Service层的查询方法，返回Note对象
        Blog blog = bs.searchBlogById(Integer.parseInt(blogId));
        // 3. 将Note对象设置到request请求域中
        request.setAttribute("blog", blog);
        // 4. 设置首页动态包含的页面值
        request.setAttribute("changePage","note/detail.jsp");
        //发表用户
        User user = (User) request.getSession().getAttribute("user");
        //登录用户执行一下操作
        if (user != null){

            //清空该篇博客内的未读信息（用户id和博客id）
            CommentUtil.updateNotify(Integer.parseInt(blogId), user.getId());
            //提供是否点赞信息
            int i = DianZanUtil.searchUserDianBlogStatus(Integer.parseInt(blogId), user.getId());
            request.setAttribute("dian", i);


        }

        //查询一级评论
        ArrayList<Comment> comments = CommentUtil.getBlogCommentList(Integer.parseInt(blogId));
        request.setAttribute("commentList", comments);
        //获取文章一级评论数量
        request.setAttribute("commentSize", comments.size());
        //提供二级评论数
        ArrayList<Integer> backCommentSizeList = CommentUtil.getBackCommentSizeList(Integer.parseInt(blogId));
        request.setAttribute("backCountList", backCommentSizeList);
        //获取文章全部评论数量
        int blogCommentSize = CommentUtil.getBlogCommentSize(Integer.parseInt(blogId));
        request.setAttribute("allCommentSize", blogCommentSize);

        if (user == null){
            user = new User();
            user.setId(-1);
            user.setNick("游客");
            user.setMood("Hello,World!");
            user.setHead("404.jpg");
        }
        request.setAttribute("user", user);

        //提供点赞数量
        int i2 = DianZanUtil.searchBlogDianCount(Integer.parseInt(blogId));
        request.setAttribute("dianCount", i2);



        //获取文章全部二级评论列表
        ArrayList<ArrayList<Comment>> list = new ArrayList<>();
        for (Comment comment : comments) {
            //获取二级评论列表
            ArrayList<Comment> backCommentSizeList1 = CommentUtil.getCommentBackList(comment.getId());
            list.add(backCommentSizeList1);
        }
        request.setAttribute("backCommentList", list);

        // 5. 请求转发跳转到index.jsp
        try {
            request.getRequestDispatcher("index.jsp").forward(request, response);
        } catch (ServletException | IOException e) {
            e.printStackTrace();
        }

    }

    private void blogComment(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //获取
        String blogId = request.getParameter("blogId");
        String fatherCommentId = request.getParameter("fatherCommentId");
        String fatherCommentUserId = request.getParameter("fatherCommentUserId");
        String text = request.getParameter("text");
        String lText = request.getParameter("lastText");

        //敏感检测
        //boolean b = bs.sensitiveCheck(text, null, null, null);

        //防xss
        text = XssStrUtils.replaceHtmlCode(text);
        //不可超长
        if (text.length() >= 128){
            text = text.substring(0, 128);
        }

        //发表用户
        User user = (User) request.getSession().getAttribute("user");

        System.out.println(request);

        //评论
        Comment comment = CommentUtil.doComment(blogId, user.getId(), text, fatherCommentId, fatherCommentUserId, lText);

        //detail(request, response);
        //request.getRequestDispatcher("blog?actionName=detail&s=1&blogId=" + blogId).forward(request, response);
        response.sendRedirect("blog?actionName=detail&blogId=" + blogId);
    }

    private void dianZan(HttpServletRequest req, HttpServletResponse resp) {

        String status = req.getParameter("status");
        String blogId = req.getParameter("blogId");

        User user = (User) req.getSession().getAttribute("user");
        //返回点赞数量
        ResultInfo<Integer> resultInfo = new ResultInfo<>();
        int i;
        if ("1".equals(status)){
            //已经点过赞，所以取消点赞
            i = DianZanUtil.cancelDianZan(Integer.parseInt(blogId), user.getId());
        }else {
            //点赞
            i = DianZanUtil.dianZan(Integer.parseInt(blogId), user.getId());
        }
        resultInfo.setCode(i);
        resultInfo.setResult(DianZanUtil.searchBlogDianCount(Integer.parseInt(blogId)));
        JsonUtil.toJson(resp, resultInfo);
    }

    private void liveBlog(HttpServletRequest req, HttpServletResponse resp) throws IOException {

        String blogID = req.getParameter("id");
        int id = 0;
        if (blogID != null && blogID.length() > 0){
            id = Integer.parseInt(blogID);
            System.out.println("id:" + id);
        }

        ResultInfo<Integer> resultInfo = bs.liveBlog(id, req);
        JsonUtil.toJson(resp, resultInfo);

    }

    private void closeBlog(HttpServletRequest req, HttpServletResponse resp) throws IOException {

        String blogID = req.getParameter("id");
        int id = 0;
        if (blogID != null && blogID.length() > 0){
            id = Integer.parseInt(blogID);
            System.out.println("id:" + id);
        }

        ResultInfo<Integer> resultInfo = bs.closeBlog(id, req);
        JsonUtil.toJson(resp, resultInfo);
    }

    private void openBlog(HttpServletRequest req, HttpServletResponse resp) throws IOException {

        String blogID = req.getParameter("id");
        int id = 0;
        if (blogID != null && blogID.length() > 0){
            id = Integer.parseInt(blogID);
            System.out.println("id:" + id);
        }

        ResultInfo<Integer> resultInfo = bs.openBlog(id, req);
        JsonUtil.toJson(resp, resultInfo);

    }

    private void deleteBlog(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String blogID = req.getParameter("id");
        int id = 0;
        if (blogID != null && blogID.length() > 0){
            id = Integer.parseInt(blogID);
            System.out.println("id:" + id);
        }

        ResultInfo<Integer> resultInfo = bs.deleteBlog2(id, req);
        JsonUtil.toJson(resp, resultInfo);
    }

    /**
     * 删除云记
     1. 接收参数 （noteId）
     2. 调用Service层删除方法，返回状态码 （1=成功，0=失败）
     3. 通过流将结果响应给ajax的回调函数 （输出字符串）
     * @param request
     * @param response
     */
    private void blogDelete(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 1. 接收参数 （noteId）
        String blogId = request.getParameter("blogId");
        // 2. 调用Service层删除方法，返回状态码 （1=成功，0=失败）
        Integer code = bs.deleteBlog(blogId, request);
        // 3. 通过流将结果响应给ajax的回调函数 （输出字符串）
        response.getWriter().write(code + "");
        response.getWriter().close();
    }

    /**
     * 添加或修改操作
     1. 接收参数 （类型ID、标题、内容）
     2. 调用Service层方法，返回resultInfo对象
     3. 判断resultInfo的code值
     如果code=1，表示成功
     重定向跳转到首页 index
     如果code=0，表示失败
     将resultInfo对象设置到request作用域
     请求转发跳转到note?actionName=view
     * @param request
     * @param response
     */
    private void addOrUpdate(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        // 1. 接收参数 （类型ID、标题、内容）
        String typeId = request.getParameter("typeId");
        String title = request.getParameter("title").trim();
        String content = request.getParameter("content");

        //标题防止xss注入
        title = XssStrUtils.replaceHtmlCode(title);

        String open = request.getParameter("open");
        int isOpen = -1;
        if (open != null && open.length() > 0){
            isOpen = Integer.parseInt(open);
            if (isOpen != 1){
                isOpen = 0;
            }
            int typeID = Integer.parseInt(typeId);
            Type type = new TypeServiceImpl().searchTypeById(typeID);
            User user = (User) request.getSession().getAttribute("user");
            if (isOpen == 1){
                //敏感词检测
                boolean flag = bs.sensitiveCheck(title, type.getName(), content, user.getName());

                if (!flag){
                    isOpen = 0;
                }
            }
        }

        System.out.println("isOpen:" + isOpen);
        // 获取经纬度
        String lon = request.getParameter("lon");
        String lat = request.getParameter("lat");

        // 如果是修改操作，需要接收noteId
        String blogId = request.getParameter("blogId");

        // 2. 调用Service层方法，返回resultInfo对
        ResultInfo<Blog> resultInfo = bs.addOrUpdate(typeId, title, content, blogId, lon, lat, isOpen, request);

        // 3. 判断resultInfo的code值
        if (resultInfo.getCode() == 1) {
            // 重定向跳转到首页 index
            response.sendRedirect("index");
        } else {

            Blog blog = new Blog();
            blog.setTypeID(Integer.parseInt(typeId));
            blog.setContent(content);
            blog.setTitle(title);
            resultInfo.setResult(blog);
            // 将resultInfo对象设置到request作用域
            request.setAttribute("resultInfo", resultInfo);
            // 请求转发跳转到note?actionName=view
            String url = "blog?actionName=view";
            // 如果是修改操作，需要传递noteId
            if (!StrUtil.isBlank(blogId)) {
                url += "&blogId="+blogId;
            }
            request.getRequestDispatcher(url).forward(request, response);
        }

    }


    /**
     * 查询云记详情
     1. 接收参数 （noteId）
     2. 调用Service层的查询方法，返回Note对象
     3. 将Note对象设置到request请求域中
     4. 设置首页动态包含的页面值
     5. 请求转发跳转到index.jsp
     * @param request
     * @param response
     */
    private void blogDetail(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1. 接收参数 （noteId）
        String blogId = request.getParameter("blogId");

        //增加浏览量
        int i1 = bs.addViewCount(Integer.parseInt(blogId));

        detail(request, response);

        /*

        // 2. 调用Service层的查询方法，返回Note对象
        Blog blog = bs.searchBlogById(Integer.parseInt(blogId));
        // 3. 将Note对象设置到request请求域中
        request.setAttribute("blog", blog);
        // 4. 设置首页动态包含的页面值
        request.setAttribute("changePage","note/detail.jsp");

        //发送用户信息，用于判断是否是本人博客
        User user = (User) request.getSession().getAttribute("user");

        //查询一级评论
        ArrayList<Comment> comments = CommentUtil.getBlogCommentList(Integer.parseInt(blogId));
        request.setAttribute("commentList", comments);
        //获取文章一级评论数量
        request.setAttribute("commentSize", comments.size());
        //提供二级评论数
        ArrayList<Integer> backCommentSizeList = CommentUtil.getBackCommentSizeList(Integer.parseInt(blogId));
        request.setAttribute("backCountList", backCommentSizeList);
        //获取文章全部评论数量
        int blogCommentSize = CommentUtil.getBlogCommentSize(Integer.parseInt(blogId));
        request.setAttribute("allCommentSize", blogCommentSize);




        //提供点赞数量
        int i2 = DianZanUtil.searchBlogDianCount(Integer.parseInt(blogId));
        request.setAttribute("dianCount", i2);

        //提供是否点赞信息
        int i = DianZanUtil.searchUserDianBlogStatus(Integer.parseInt(blogId), user.getId());
        request.setAttribute("dian", i);

        System.out.println(request);
        request.setAttribute("user", user);

        // 5. 请求转发跳转到index.jsp
        request.getRequestDispatcher("index.jsp").forward(request, response);*/
    }

    /**
     * 进入发布云记页面
     1. 从Session对象中获取用户对象
     2. 通过用户ID查询对应的类型列表
     3. 将类型列表设置到request请求域中
     4. 设置首页动态包含的页面值
     5. 请求转发跳转到index.jsp
     * @param request
     * @param response
     */
    private void blogView(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        /* 修改操作 */
        // 得到要修改的云记ID
        String id = request.getParameter("blogId");
        int blogId = -1;
        if (id != null && id.length() > 0){
            blogId = Integer.parseInt(id);
        }
        System.out.println("blogId:" + blogId);
        // 通过noteId查询云记对象
        Blog blog = bs.searchBlogById(blogId);
        // 将note对象设置到请求域中
        request.setAttribute("blogInfo", blog);
        /* 修改操作 */


        // 1. 从Session对象中获取用户对象
        User user = (User) request.getSession().getAttribute("user");
        // 2. 通过用户ID查询对应的类型列表
        List<Type> typeList = new TypeServiceImpl().findTypeList(user.getId());
        // 3. 将类型列表设置到request请求域中
        request.setAttribute("typeList", typeList);

        // 4. 设置首页动态包含的页面值
        request.setAttribute("changePage","note/view.jsp");
        // 5. 请求转发跳转到index.jsp
        request.getRequestDispatcher("index.jsp").forward(request, response);

    }

}
